﻿/*
 * Copyright (c) Huawei Technologies Co., Ltd. 2020-2020. All rights reserved.
 * Description: 4K 以及特有功能
 * Author: 辛爱国 x30005137
 * Create: 2020-08-18
 * Notes: 无
 */
#include <QFont>
#include <QFontMetrics>
#include <qpushbutton.h>
#include <qicon.h>
#include <qvariant.h>
#include <qpixmap.h>
#include <QApplication>
#include <QDesktopWidget>
#include <qstyle.h>
#include <qcombobox.h>
#include <qabstractitemview.h>
#include <qslider.h>
#include <qcheckbox.h>
#include <qradiobutton.h>
#include <qlabel.h>
#include <qnamespace.h>
#include <qscreen.h>
#include <QDebug>
#include "HWDialog.h"
HWDialog::HWDialog(QWidget *parent) : QDialog(parent)
{}
bool HWDialog::event(QEvent *event)
{
    QDesktopWidget *desktopwidget = QApplication::desktop();
    QObject::connect(desktopwidget, SIGNAL(resized(int)), this, SLOT(resizeWindow()), Qt::UniqueConnection);

    for (auto &screen : QApplication::screens()) {
        QObject::connect(screen, SIGNAL(logicalDotsPerInchChanged(qreal)), this, SLOT(resizeWindow()), Qt::UniqueConnection);
    }
    return QDialog::event(event);
}
HWDialog::~HWDialog()
{}
void HWDialog::mousePressEvent(QMouseEvent *event)
{
    QApplication::setActiveWindow(this);
    if (QApplication::activeWindow() != nullptr) {
        qDebug() << "current activationName " << QApplication::activeWindow()->objectName();
    }
    if (event->button() == Qt::LeftButton) {
        m_isMoveWindow = true;
        // 获得鼠标的初始位置
        m_mouseStartPoint = event->globalPos();
        // 获得窗口的初始位置
        m_windowTopLeftPoint = this->frameGeometry().topLeft();
    }
}
void HWDialog::mouseMoveEvent(QMouseEvent *event)
{
    if (m_isMoveWindow) {
        // 获得鼠标移动的距离
        QPoint distance = event->globalPos() - m_mouseStartPoint;
        // 改变窗口的位置
        this->move(m_windowTopLeftPoint + distance);
        resizeWindow();
        this->move(m_windowTopLeftPoint + distance);
    }
}
void HWDialog::mouseReleaseEvent(QMouseEvent *event)
{
    if (event->button() == Qt::LeftButton) {
        m_isMoveWindow = false;
    }
}

void HWDialog::saveChildrenInfo()
{
    this->setProperty("RootDialog", true);
    saveSingelWidget(this);
    QList<QWidget *> listWid = this->findChildren<QWidget *>();
    for (auto &hl : listWid) {
        saveSingelWidget(hl);
    }
    QList<QPushButton *> listbutton = this->findChildren<QPushButton *>();
    for (auto &hl : listbutton) {
        if (!hl->icon().isNull()) {
            QSize size = hl->iconSize();
            hl->setProperty("ICONSIZE", size);
        }
    }
    QList<QComboBox *> listbox = this->findChildren<QComboBox *>();
    for (auto &hl : listbox) {
        QString name = hl->objectName();
        QAbstractItemView *items = hl->view();
        int itemHeight = items->childrenRect().height();
        hl->setProperty("ITEMHEIGHT", itemHeight);
    }
    QList<QCheckBox *> listcheckbox = this->findChildren<QCheckBox *>();
    for (auto &hl : listcheckbox) {
        QRect rec = hl->contentsRect();
        hl->setProperty("INDICATORC", rec.height() * 0.6); // 0.6为指示符与高度比率
    }
    QList<QRadioButton *> listradio = this->findChildren<QRadioButton *>();
    for (auto &hl : listradio) {
        QRect rec = hl->contentsRect();
        hl->setProperty("INDICATORL", rec.height() * 0.6); // 0.6为指示符与高度比率
    }
    QList<QSlider *> listslider = this->findChildren<QSlider *>();
    for (auto &hl : listslider) {
        QRect rec = hl->contentsRect();
        int WID = hl->frameSize().height();
        hl->setProperty("INDICKATOR", WID); // 0.6为指示符与高度比率
        hl->setProperty("LASTRATE", getCurrentRate(hl)); // 0.6为指示符与高度比率
    }
}
void HWDialog::saveSingelWidget(QWidget *wid)
{
    wid->style()->unpolish(wid);
    wid->style()->polish(wid);
    wid->update();
    QRect Range;
    // 控件的最大最小
    Range.setLeft(wid->minimumWidth());
    Range.setRight(wid->maximumWidth());
    Range.setBottom(wid->minimumHeight());
    Range.setTop(wid->maximumHeight());
    wid->setProperty("ALLRANGEL", Range);
    // 设置大小
    QString name = wid->objectName();
    if (name == "") {
    }
    QRect rectWin = wid->geometry();
    wid->setProperty("ALLRECTWIN", rectWin);
    int fontsize = wid->font().pixelSize();
    wid->setProperty("ALLWINFONTH", fontsize);
}
void HWDialog::resizeEvent(QResizeEvent *event)
{
    QWidget::resizeEvent(event);
    resizeWindow();
}
void HWDialog::resizeWindow()
{
    double rate = getCurrentRate(this);
    if (std::fabs(m_rate - rate) < 1e-3)
        return;
    m_rate = rate;

    QList<QWidget *> listWidgets = this->findChildren<QWidget *>();
    for (auto &lw : listWidgets) {
        scalWidgets(lw);
    }
    scalLabel(this);
    scalPushButton(this);
    scalCheckBox(this);
    scalCombox(this);
    scalSlider(this);
    scalWidgets(this);
}
void HWDialog::scalWidgets(QWidget *wid)
{
    if (wid == nullptr) {
        return;
    }
    double rate = getCurrentRate(wid);
    // 窗口大小
    QRect rectrange = wid->property("ALLRANGEL").toRect();
    // 最小值
    wid->setMaximumHeight((rectrange.top() * rate > 16777215) ? 16777215 : (rectrange.top() * rate)); // 16777215窗口最大值
    wid->setMinimumHeight(rectrange.bottom() * rate);
    wid->setMaximumWidth((rectrange.right() * rate) > 16777215 ? 16777215 : (rectrange.right() * rate)); // 16777215窗口最大值
    wid->setMinimumWidth(rectrange.left() * rate);
    // 最大值
    QString name = wid->objectName();
    if (name == "") {
    }
    QRect sat = wid->property("ALLRECTWIN").toRect();
    QRect bct = wid->geometry();
    // 窗口X
    if (wid != findFinalParent(wid)) {
        bct.setX(sat.x() * rate);
        bct.setY(sat.y() * rate);
    }
    // 窗口长宽
    bct.setWidth((sat.width() * rate < 1) ? 1 : (sat.width() * rate));
    bct.setHeight((sat.height() * rate < 1) ? 1 : (sat.height() * rate));
    wid->setGeometry(bct);
    // 字体
    QFont font = wid->font();
    int FontHeight = wid->property("ALLWINFONTH").toInt();
    if (FontHeight > 0) {
        font.setPixelSize(FontHeight * rate);
        wid->ensurePolished();
        wid->setFont(font);
    }
}
void HWDialog::scalPushButton(QWidget *wid)
{
    QList<QPushButton *> listbutton = wid->findChildren<QPushButton *>();
    for (auto &hl : listbutton) {
        if (hl == nullptr) {
            continue;
        }
        double rate = getCurrentRate(hl);

        QString name = hl->objectName();
        int sizeFont = hl->property("ALLWINFONTH").toInt() * rate;
        QSize size = hl->property("ICONSIZE").toSize() * rate;

        if (sizeFont > 0) {
            hl->setStyleSheet(QString("qproperty-iconSize:%1px %2px;font-size: %3px;").
                              arg(size.width()).arg(size.height()).arg(sizeFont));
        } else {
            hl->setStyleSheet(QString("qproperty-iconSize:%1px %2px;").
                              arg(size.width()).arg(size.height()));
        }
    }
}
void HWDialog::scalCheckBox(QWidget *wid)
{
    QList<QCheckBox *> listWid = wid->findChildren<QCheckBox *>();
    for (auto &hl : listWid) {
        double rate = getCurrentRate(hl);
        QString name = hl->objectName();
        int Height = hl->property("INDICATORC").toInt() * rate;
        int sizeFont = hl->property("ALLWINFONTH").toInt() * rate;
        if (sizeFont > 0) {
            hl->setStyleSheet(QString("QCheckBox{font-size:%1px;}").arg(sizeFont) +
                              QString("QCheckBox::indicator{width: %1px;height: %2px;}").
                              arg(Height).arg(Height)); // 10 biankuang
        } else {
            hl->setStyleSheet(QString("QCheckBox::indicator{width: %1px;height: %2px;}").
                              arg(Height).arg(Height)); // 10 biankuang
        }
    }

    QList<QRadioButton *> listra = wid->findChildren<QRadioButton *>();
    for (auto &hl : listra) {
        double rate = getCurrentRate(hl);
        QString name = hl->objectName();
        if (name == "") {
        }
        int Height = hl->property("INDICATORL").toInt() * rate;
        int sizeFont = hl->property("ALLWINFONTH").toInt() * rate;
        if (sizeFont > 0) {
            hl->setStyleSheet(QString("QRadioButton{font-size:%1px;}").arg(sizeFont) +
                              QString("QRadioButton::indicator{width: %1px;height: %2px;}").
                              arg(Height).arg(Height)); // 10 biankuang
        } else {
            hl->setStyleSheet(QString("QRadioButton::indicator{width: %1px;height: %2px;}").
                              arg(Height).arg(Height)); // 10 biankuang
        }
    }
}
void HWDialog::scalSlider(QWidget *wid)
{
    QList<QSlider *> listWid = wid->findChildren<QSlider *>();
    for (auto &hl : listWid) {
        double rate = getCurrentRate(hl);
        if (hl->orientation() == Qt::Horizontal) {
            double lastrate = hl->property("LASTRATE").toDouble();
            int currentValue = hl->value() * rate / lastrate;
            hl->setProperty("LASTRATE", rate);
            QRect rector = hl->property("ALLRECTWIN").toRect();
            int rectHeight = rector.height();
            int leftrightGroove = (rectHeight / 2.0 - 1) * rate;  // 2.0去一半 1个单位
            int leftrighthandle = rectHeight / 2.0 * rate;  // 2.0 取中值
            int widgrove = 2.0 * rate;   // 滑条宽2.0
            int mover = rectHeight / 2.0 * rate; // 2.0 取中值
            int handleHeight = rate * rectHeight + widgrove;
            QRect rect = hl->geometry();
            rect.setX(rector.x() * rate - leftrightGroove);  // 1.0 基础倍率
            rect.setY(rector.y() * rate);
            // 窗口长宽
            int width = rector.width() * rate + leftrightGroove * 2.0;  // 1.0 基础倍率 2.0 两边同时加
            rect.setWidth((width < 1) ? 1 : width);
            hl->setRange(0, width);
            rect.setHeight((rector.height() * rate < 1) ? 1 : (rector.height() * rate));
            hl->setGeometry(rect);
            hl->setStyleSheet(QString("QSlider::groove:horizontal{ height: %1px; left: %2px; right: %3px; }").arg(widgrove).
                              arg(leftrightGroove).arg(leftrightGroove) +
                              QString("QSlider::handle:horizontal{ width: %1px; margin: -%3px -%4px -%5px -%6px; }").arg(handleHeight).
                              arg(mover).arg(mover).arg(mover).arg(mover)); // 10 biankuang
            hl->setValue(currentValue);
        }
    }
}
void HWDialog::scalLabel(QWidget *wid)
{
    QList<QLabel *> listlabel = wid->findChildren<QLabel *>();
    for (auto &hl : listlabel) {
        double rate = getCurrentRate(hl);
        QString name = hl->objectName();
        if (name == "") {
        }
        int sizeFont = hl->property("ALLWINFONTH").toInt() * rate;
        if (sizeFont > 0) {
            hl->setStyleSheet(QString("font-size: %3px;").
                              arg(sizeFont));
        }
    }
}
void HWDialog::scalCombox(QWidget *wid)
{
    // 按钮
    QList<QComboBox *> listbutton = wid->findChildren<QComboBox *>();
    for (auto &hl : listbutton) {
        double rate = getCurrentRate(hl);
        QString name = hl->objectName();
        if (name == "") {
        }
        QAbstractItemView *items = hl->view();
        int heighthl = hl->property("ITEMHEIGHT").toInt() * rate;
        int sizeFont = hl->property("ALLWINFONTH").toInt() * rate;
        if (sizeFont > 0) {
            hl->setStyleSheet(QString("QComboBox{font-size:%1px;}").arg(sizeFont) +
                              QString("QAbstractItemView{font-size:%1px;}").arg(sizeFont) +
                              QString("QAbstractItemView::item{height: %1px;}").arg(heighthl));
        } else {
            hl->setStyleSheet(QString("QAbstractItemView::item{height: %1px;}").arg(heighthl));
        }
    }
}

QWidget *CommenMethod::findFinalParent(QWidget *wid)
{
    QWidget *ret = wid;
    while (ret != nullptr) {
        if (!ret->property("RootDialog").isNull() && ret->property("RootDialog").toBool()) {
            break;
        }
        ret = ret->parentWidget();
    }
    ret = ((ret == nullptr) ? wid : ret);
    return ret;
}

double CommenMethod::getCurrentRate(QWidget *wid)
{
    if (wid == nullptr) {
        return m_rate;
    }
    QWidget *parentWid = findFinalParent(wid);
    QPoint pt = parentWid->pos();
    if (m_UseCenter) {
        pt = parentWid->geometry().center();
    }
    QScreen *screen = QApplication::screenAt(pt);
    if (screen == nullptr) {
        return m_rate;
    }
    double ret = screen->logicalDotsPerInch() / 96.0; // 分辨率和基础比较比率96.0
    if (ret < 1.1) {                                  // 比例比1.1小
        ret = 1.0;                                    // 结果1.0
    } else if (ret < 1.4) {                           // 比例比1.4小
        ret = 1.25;                                   // 结果1.25
    } else if (ret < 1.6) {                           // 比例比1.6小
        ret = 1.5;                                    // 结果 1.5
    } else if (ret < 1.8) {                           // 比例比1.8小
        ret = 1.75;                                   // 结果1.75
    } else if (ret < 2.1) {                           // 比例比2.1小
        ret = 2.0;                                    // 结果2.0
    } else if (ret < 2.3) {                           // 比2.3小
        ret = 2.25;                                   // 结果2.25
    } else if (ret < 2.8) {                           // 比2.8小
        ret = 2.5;                                    // 结果2.5
    } else if (ret < 3.2) {                           // 比3.2小
        ret = 3.0;                                    // 结果3.0
    } else {
        ret = 3.5;                                    // 最大3.5
    }

    return ret;
}